<template>
  <div class="app-container" >
 
    <el-form v-model="searchData" inline label-width="100px" >
      <el-form-item label="项目名称">
        <project-select v-model="searchData.project_id" @change="refresh"></project-select>
      </el-form-item>
      <el-form-item label="直播名称">
        <el-input placeholder="请输入名称进行搜索" v-model="searchData.live_name" @change="refresh"> </el-input>
      </el-form-item>
    </el-form>

    <el-row :gutter="20" ref="videoContainer">
      <el-col :span="8" v-for="(video, index) of videos" :key="video.uu_id">
        <ft-video-player
          class="video-container" 
          :style="{height: videoContainerHeight + 'px'}"
          :ref="'player' + index"
          :source="video.source"
          :poster="video.poster"
          @play="play(video)"
          @stop="stop(video)"
          :data="video"
          :operationPanel="video.is_onvif"
          :showSetting="false"
          @directive="directive(video,$event)"
        ></ft-video-player>
      </el-col>
    </el-row>
    <el-row type="flex" justify="center" class="pagination">
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :page-size="page.size"
        :current-page="page.currentPage"
        layout="total,  prev, pager, next, jumper"
        :total="page.total"
        hide-on-single-page
      ></el-pagination>
    </el-row>
    <!-- <specially-signal-demo></specially-signal-demo> -->
  </div>
</template>

<script>
import { findLive } from "@/api/video";

import FtVideoPlayer from "@/library/ui/ft-video-player";
import  WS  from "@/library/js/ws";
import { v4 as uuidv4 } from "uuid";

import ProjectSelect from '@/views/components/ProjectSelect'
// import config from '../../../video.config.js'
import {config} from "../../../../../config/env-configs"

// import SpeciallySignalDemo from '@/library/ui/ft-video-player/specially-signal-demo'


export default {
  name: "VideoPlay",
  mixins: [WS],
  components: {
    FtVideoPlayer,
    ProjectSelect,
    // SpeciallySignalDemo
  },
  data: () => ({
    searchData: {},
    showDialog: false,
    searchStr: '',
    videos:[],
    videoContainerHeight: 200,
    activedCameras: [],
    clientId: 0,
    errMsg:{
      0: "正常",
      1: "推流服务端链接流媒体服务网络故障",
      2: "推流服务端连接摄像头网络故障",
      3: "并行推流路数超限",
      4: "推流服务端主机内存不足",
      5: "onvif探测失败",
      6: "onvif 获取能力失败",
      7: "onvif 云台控制失败",
      11: "流媒体服务未启动", //前端页面判断
      12: "请求的 rtmp 流不存在；原因推流服务未运行或 rtmp 地址错误", //前端页面判断
    },
    timer: null,
    detectionTimer: null,
    detectionTimer2: null,
    page: {
      size: 9,
      currentPage: 1,
      total: 0
    },
    videoCache:{}
  }),
  mounted: async function() {
    this.clientId = uuidv4();
    this.getVideoContainerWidth(); 
    window.addEventListener('resize', this.getVideoContainerWidth);
    await  this.refresh();
    this.waitWsConnected();
  },

  watch: {
    async readyState() {
      //ws连接状态
      if (this.readyState === 1) {
       
     
      }
    }
  },
  methods: {
   waitWsConnected(){
      this.detectionTimer = setInterval( async() => { //检测是否ws已连接
        if(this.readyState){
          clearInterval(this.detectionTimer);

          await this.registVideoClient();
          this.ws.onmessage = ({data}) => {
            data = JSON.parse(data)
            if(data.type_no === 102 && data.onvif_ptz_ability){//云台控制
                this.videos.forEach((item, i)=>{
                  if(item.camera_info && item.camera_info.uu_id === data.camera_id){
                    item.is_onvif = true;
                    this.$set(this.videos, i, item)
                  } 
                })
            } 
            const code = data.error_no;
            if(code && code !== 5 && code !== 6 && code !== 7){
              this.$message({
                type: 'error',
                message: this.errMsg[data.error_no]
              })
            }
          };
        }
      }, 100);
    },
    async refresh() {
      this.activedCameras = [];
      let params = {
        project_id: this.searchData.project_id,
        live_name: this.searchData.live_name
      }
      this.videos = [];

      let {data} = await findLive(this.page, params);
      if (data.errno === 0) {
        this.page.total = data.total_num;
        if(!data.live || data.live.length === 0) return;
        data.live.forEach((video, i)=>{
          video.source = {
              src:  'rtmp://' + video.push_domain_name+ '/'+ video.push_app_name + '/' + video.push_stream_name +(video.authed_key ? `?authedkey=${video.authed_key}`: ''),
              type: "rtmp/flv"
          }
          video.poster =  config.video.baseURL + '/image' + video.preview_path
          this.$set(this.videos, i, video)
        })
      } else {
        this.$message({
          type: "warning",
          message: res.data.errno
        });
      }
    },
    async getVideoContainerWidth() {
      let width = this.$refs.videoContainer.$el.clientWidth - 10 * 5;
      this.videoContainerHeight = (width / 16) * 3 + 30; //(width/3/16*9)3列
    },
    async registVideoClient() {
      let data = {
        type_no: 200,
        regist_name:  this.clientId,
        project_id: this.videos[0].camera_info.project_id,
      };
      this.sendData(data); //注册
    },
    async sendData(data){
        if(this.ws) this.ws.send(JSON.stringify(data));
    },
    sendHeartbeat(video){
      this.timer = setInterval(() => {
        if(this.activedCameras.length === 0){
          clearInterval( this.timer)
          this.timer = null;
          return
        } 
        let data = {
          type_no: 203,
          forward: true,
          from: this.clientId,
          to: video.camera_info.push_id,
          project_id: video.camera_info.project_id,
          heart: this.activedCameras
        };
        this.sendData(data)
      }, 10000);
    },
    play(video){
      if(video.is_disable){
        this.$message({
          type: 'warning',
          message: `摄像头${video.push_stream_name}被禁止推流`
        })
        return;
      }
      if(video.push_dev_type !== 1) return; //只有rtsp流的摄像头需要 转码//rtmp的属于直连
      this.videoCache[video.uu_id] = video;
      if(this.readyState !== 1){
        this.detectionTimer2 = setInterval(()=>{ //检测是否ws已连接
          if(this.readyState ===1){ 
            clearInterval(this.detectionTimer2)
            for(let key in this.videoCache){
              this.fetchPlay(this.videoCache[key]);
              delete this.videoCache[key]
            }
          }
        })
        return;
      }else{
        this.fetchPlay(video);
      }
    },
    fetchPlay(video){
      let flag = this.activedCameras.some( uu_id=>{
        return uu_id === video.camera_info.uu_id;
      })
      if(!flag) this.activedCameras.push( video.camera_info.uu_id)
      else return
      let rtsp = video.camera_info.rtsp_url.split('//')
      let data = {
        type_no: 201,
        forward: true,
        project_id: video.camera_info.project_id,
        from: this.clientId,
        to: video.camera_info.push_id,
        rtsp_url: rtsp[0] + '//' + video.camera_info.user_name  +':' + video.camera_info.password + '@' + rtsp[1],
        rtmp_url: 'rtmp://' + video.push_domain_name+ '/'+ video.push_app_name + '/' + video.push_stream_name +(video.authed_key ? `?authedkey=${video.authed_key}`: ''),
        camera_id: video.camera_info.uu_id,
        ip: video.camera_info.ip,
        user_name: video.camera_info.user_name,
        password:  video.camera_info.password
      };
      this.sendData(data)//请求推流
      if(!this.timer) this.sendHeartbeat(video);
    },
    stop(video){
      let data = {
        type_no: 202,
        forward: true,
        from: this.clientId,
        to: video.camera_info.push_id,
        project_id: video.camera_info.project_id,
        rtsp_url: video.camera_info.rtsp_url
      };

      this.sendData(data)
      this.activedCameras = this.activedCameras.filter(item => {
        return item !== video.camera_info.uu_id;
      });
    },
    directive(video, directive){//控制转动和焦距
      let data = {
        type_no: 204,
        forward: true,
        from: this.clientId,
        to: video.camera_info.push_id,
        ip: video.camera_info.ip,
        camera_id: video.camera_info.uu_id,
        project_id: video.camera_info.project_id,
        ptz_command: directive
      };
      this.sendData(data)
    },
    handleSizeChange(size) {
      this.page.currentPage = 1;
      this.page.size = size;
      this.refresh();
    },
    handleCurrentChange(page) {
      this.page.currentPage = page;
      this.refresh();
    }
 
  },
  deactived(){
    clearInterval(this.timer)
    clearInterval(this.detectionTimer);
    clearInterval(this.detectionTimer2);
    this.timer = null;
    this.detectionTimer = null;
    this.detectionTimer2 = null;
    window.removeEventListener('resize', this.getVideoContainerWidth)

  },
  beforeDestroy(){
    clearInterval(this.timer)
    clearInterval(this.detectionTimer);
    clearInterval(this.detectionTimer2);
    this.timer = null;
    this.detectionTimer = null;
    this.detectionTimer2 = null;
    window.removeEventListener('resize', this.getVideoContainerWidth)

  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss"  scoped>
.app-container{
  padding: 10px;

  .video-container {
  display: flex;
  margin-bottom: 20px;
  flex-direction: column;
  border: 1px solid #c7c0c0;
  border-radius: 4px;
  > .el-image {
    width: 100%;
    height: 100%;
  }
  > .el-image ::v-deep .el-image__error {
    background: gray !important;
  }
  > .ft-video-player {
    width: 100%;
    height: 100%;
  }
}
}

</style>
